package com.kamistoat.meimeimall.common.annotation.annotationHandler;

import com.kamistoat.meimeimall.common.annotation.DubboAndHTTPExceptionCatch;
import com.kamistoat.meimeimall.common.exception.BizCodeEnum;
import com.kamistoat.meimeimall.common.exception.RRException;
import com.kamistoat.meimeimall.common.utils.R;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 处理 {@link DubboAndHTTPExceptionCatch} 注解.
 * 注意，由于 common 模块不具备主启动类，也就无法自动扫描 Component.
 * 因此需要手动在 SPI 文件中指定这些 Component 进行注入.
 * <p></p>
 * 顺序-50，比全局登录拦截器 {@link com.kamistoat.meimeimall.common.interceptor.GlobalLoginInterceptor} 级别低.
 */
@Aspect
@Component
@Order(-50)
public class DubboAndHTTPExceptionCatchHandler {
    @Around(value = "@annotation(dubboAndHTTPExceptionCatch)")
    public R innerAround(ProceedingJoinPoint proceedingJoinPoint, DubboAndHTTPExceptionCatch dubboAndHTTPExceptionCatch) throws Throwable {
        try {
            // 执行切面逻辑。如果切面无异常抛出，则说明此切面的RPC业务逻辑没有异常。
            // 但下游的RPC业务可能存在异常并传递回来。
            // 因此这里不需要做修改直接返回即可
            return (R) proceedingJoinPoint.proceed();
        } catch (Exception e) {
            // 否则说明此切面的RPC有异常.检查是何种异常
            if(e instanceof RRException) {
                return R.error(((RRException) e).getCode(), ((RRException) e).getMsg());
            }else {
                return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), e.toString());
            }
        }
    }
}
